package com.daka.controller;

import com.alibaba.fastjson.JSONObject;
import com.daka.annotation.Login;
import com.daka.entity.GroupVolunteer;
import com.daka.entity.Organization;
import com.daka.enumerate.StatusCode;
import com.daka.service.OrganizationCountService;
import com.daka.service.OrganizationService;
import com.daka.vo.db.ActivityCountVo;
import com.daka.vo.db.VolunteerTimeVo;
import com.daka.vo.response.DataResponseVo;
import com.daka.vo.response.ListDataResponseVo;
import com.daka.vo.response.statistics.ActivityCountResponseVo;
import com.daka.vo.response.statistics.GroupCountVo;
import com.daka.vo.response.statistics.TimeCountResponseVo;
import com.daka.vo.response.statistics.VolunteerCountResponseVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * @author beliveli on 2016/8/1/0001
 */
@Controller
@RequestMapping("/statistics")
@Slf4j
public class StatisticsController {

    @Resource
    private OrganizationCountService organizationCountService;

    @Resource
    private OrganizationService organizationService;

    int yes = 1;
    int no = 2;
    int count = 999;

    @ResponseBody
    @RequestMapping(method = RequestMethod.POST, value = "/groupCount", consumes = "application/json")
    @Login
    public DataResponseVo<GroupCountVo> groupCount(@RequestBody JSONObject jsonObj, HttpSession session) {
        String startDate = jsonObj.getString("startDate");
        String endDate = jsonObj.getString("endDate");
        String jurisdiction = jsonObj.getString("jurisdiction");

        if (StringUtils.isEmpty(startDate) || StringUtils.isEmpty(startDate)) {
            return new DataResponseVo<>(StatusCode.PARAM_ERROR.getStatusCode(), StatusCode.PARAM_ERROR.getStatusMessage());
        }

        int orgId = Integer.parseInt(session.getAttribute("orgId").toString());

        Organization organization = organizationService.selectById(orgId);

        if (StringUtils.isEmpty(jurisdiction)) {
            jurisdiction = organization.getJurisdiction();
        }
        jurisdiction = jurisdiction.replaceAll("0*$","");
        GroupCountVo groupCountVo = organizationCountService.selectGroupCount(orgId, 2, organization.getPlatformId(), startDate, endDate, jurisdiction);
        return new DataResponseVo<>(StatusCode.SUCCESS.getStatusCode(), StatusCode.SUCCESS.getStatusMessage(), groupCountVo);
    }

    @ResponseBody
    @RequestMapping(method = RequestMethod.POST, value = "/activityCount", consumes = "application/json")
    @Login
    public ListDataResponseVo<ActivityCountResponseVo> activityCount(@RequestBody JSONObject jsonObj, HttpSession session) {
        String startDate = jsonObj.getString("startDate");
        String endDate = jsonObj.getString("endDate");
        String jurisdiction = jsonObj.getString("jurisdiction");
        List<ActivityCountResponseVo> resultList = new ArrayList<>();
        int signCount = 0;
        int realCount = 0;
        int timeCount = 0;
        int activityCount = 0;
        int hasGroup = 0;
        int allGroup = 0;


        if (StringUtils.isEmpty(startDate) || StringUtils.isEmpty(startDate)) {
            return new ListDataResponseVo<>(StatusCode.PARAM_ERROR.getStatusCode(), StatusCode.PARAM_ERROR.getStatusMessage());
        }

        int orgId = Integer.parseInt(session.getAttribute("orgId").toString());


        Organization organization = organizationService.selectById(orgId);

        if (StringUtils.isEmpty(jurisdiction)) {
            jurisdiction = organization.getJurisdiction();
        }
        jurisdiction = jurisdiction.replaceAll("0*$","");
        List<ActivityCountVo> activityCountYes = organizationCountService.selectActivityYes(orgId, 2, organization.getPlatformId(), startDate, endDate);
        List<Integer> codeYes = organizationCountService.selectActivityCountYes(orgId, 2, organization.getPlatformId(), startDate, endDate);
        List<ActivityCountVo> activityCountList = organizationCountService.selectActivity(orgId, organization.getPlatformId(), startDate, endDate, jurisdiction);
        List<Integer> codeList = organizationCountService.selectActivityCount(orgId, organization.getPlatformId(), jurisdiction);

        /**
         * 根据codelist和已经有挂靠关系的code计算没有挂靠关系的code codeNo
         */
        List<Integer> codeTemp = new ArrayList<>();
        List<Integer> codeNo = new ArrayList<>();
        codeTemp.addAll(codeList);
        codeNo.addAll(codeList);

        codeTemp.retainAll(codeYes);
        codeNo.removeAll(codeTemp);

//        System.out.println("yes" + codeYes);
//        System.out.println("temp" + codeTemp);
//        System.out.println("no" + codeNo);
//        System.out.println("list" + codeList);

        int signNumber = 0;
        int realNumber = 0;
        int timeNumber = 0;
        List<Integer> hasActivityGroup = new ArrayList<>();
        for (ActivityCountVo activityCountVo : activityCountYes) {
            signNumber = signNumber + activityCountVo.getApplys();
            realNumber = realNumber + activityCountVo.getAttends();
            timeNumber = timeNumber + activityCountVo.getTimes();
            hasActivityGroup.add(activityCountVo.getGroupId());
        }

        HashSet<Integer> hs = new HashSet<>(hasActivityGroup);
        signCount = signCount + signNumber;
        realCount = realCount + realNumber;
        timeCount = timeCount + timeNumber;
        activityCount = activityCount + activityCountYes.size();
        hasGroup = hasGroup + hs.size();
        allGroup = allGroup + codeYes.size();
        ActivityCountResponseVo activityCountResponseVo = ActivityCountResponseVo.build(yes, activityCountYes.size(),
                signNumber, realNumber, timeNumber, hs.size(), codeYes.size());
        resultList.add(activityCountResponseVo);

        signNumber = 0;
        realNumber = 0;
        timeNumber = 0;
        hasActivityGroup = new ArrayList<>();
        int activity = 0;
        for (ActivityCountVo activityCountVo : activityCountList) {
            if (codeNo.contains(activityCountVo.getGroupId())) {
                signNumber = signNumber + activityCountVo.getApplys();
                realNumber = realNumber + activityCountVo.getAttends();
                timeNumber = timeNumber + activityCountVo.getTimes();
                hasActivityGroup.add(activityCountVo.getGroupId());
                activity = activity + 1;
            }
        }

        hs = new HashSet<>(hasActivityGroup);
        signCount = signCount + signNumber;
        realCount = realCount + realNumber;
        timeCount = timeCount + timeNumber;
        activityCount = activityCount + activity;
        hasGroup = hasGroup + hs.size();
        allGroup = allGroup + codeNo.size();
        activityCountResponseVo = ActivityCountResponseVo.build(no, activity,
                signNumber, realNumber, timeNumber, hs.size(), codeNo.size());
        resultList.add(activityCountResponseVo);

        activityCountResponseVo = ActivityCountResponseVo.build(count, activityCount,
                signCount, realCount, timeCount, hasGroup, allGroup);
        resultList.add(activityCountResponseVo);

        return new ListDataResponseVo<>(StatusCode.SUCCESS.getStatusCode(), StatusCode.SUCCESS.getStatusMessage(), resultList);
    }

    @ResponseBody
    @RequestMapping(method = RequestMethod.POST, value = "/timeCount", consumes = "application/json")
    @Login
    public ListDataResponseVo<TimeCountResponseVo> timeCount(@RequestBody JSONObject jsonObj, HttpSession session) {
        List<TimeCountResponseVo> resultList = new ArrayList<>();
        int groupCount;
        int signCount;
        int timeCount;

        String startDate = jsonObj.getString("startDate");
        String endDate = jsonObj.getString("endDate");
        String jurisdiction = jsonObj.getString("jurisdiction");

        int orgId = Integer.parseInt(session.getAttribute("orgId").toString());

        Organization organization = organizationService.selectById(orgId);

        if (StringUtils.isEmpty(jurisdiction)) {
            jurisdiction = organization.getJurisdiction();
        }
        jurisdiction = jurisdiction.replaceAll("0*$","");
        List<Integer> codeYes = organizationCountService.selectActivityCountYes(orgId, 2, organization.getPlatformId(), startDate, endDate);
        List<Integer> codeList = organizationCountService.selectActivityCount(orgId, organization.getPlatformId(), jurisdiction);

        /**
         * 根据codelist和已经有挂靠关系的code计算没有挂靠关系的code codeNo
         */
        List<Integer> codeTemp = new ArrayList<>();
        List<Integer> codeNo = new ArrayList<>();
        codeTemp.addAll(codeList);
        codeNo.addAll(codeList);

        codeTemp.retainAll(codeYes);
        codeNo.removeAll(codeTemp);

        String strYes = StringUtils.join(codeYes, ",");
        String strNo = StringUtils.join(codeNo, ",");

        VolunteerTimeVo yesList = organizationCountService.selectTimeByVolunteer(strYes);
        VolunteerTimeVo noList = organizationCountService.selectTimeByVolunteer(strNo);
        groupCount = codeYes.size()+ codeNo.size();
        signCount = yesList.getVolunteerCount()+ noList.getVolunteerCount();
        timeCount = yesList.getTimes() + noList.getTimes();
        resultList.add(TimeCountResponseVo.build(yes, codeYes.size(), yesList.getVolunteerCount(), yesList.getTimes()));
        resultList.add(TimeCountResponseVo.build(no, codeNo.size(), noList.getVolunteerCount(), noList.getTimes()));
        resultList.add(TimeCountResponseVo.build(count, groupCount,signCount, timeCount));

        return new ListDataResponseVo<>(StatusCode.SUCCESS.getStatusCode(), StatusCode.SUCCESS.getStatusMessage(), resultList);
    }

    @ResponseBody
    @RequestMapping(method = RequestMethod.POST, value = "/volunteerCount", consumes = "application/json")
    @Login
    public ListDataResponseVo<VolunteerCountResponseVo> volunteerCount(@RequestBody JSONObject jsonObj, HttpSession session) {
        List<VolunteerCountResponseVo> resultList = new ArrayList<>();
        int allGroup = 0;
        int allSign = 0;
        int hasGroup = 0;
        int hasSign = 0;

        String startDate = jsonObj.getString("startDate");
        String endDate = jsonObj.getString("endDate");
        String jurisdiction = jsonObj.getString("jurisdiction");

        int orgId = Integer.parseInt(session.getAttribute("orgId").toString());

        Organization organization = organizationService.selectById(orgId);

        if (StringUtils.isEmpty(jurisdiction)) {
            jurisdiction = organization.getJurisdiction();
        }
        jurisdiction = jurisdiction.replaceAll("0*$","");
        List<Integer> codeYes = organizationCountService.selectActivityCountYes(orgId, 2, organization.getPlatformId(), startDate, endDate);
        List<Integer> codeList = organizationCountService.selectActivityCount(orgId, organization.getPlatformId(), jurisdiction);

        /**
         * 根据codelist和已经有挂靠关系的code计算没有挂靠关系的code codeNo
         */
        List<Integer> codeTemp = new ArrayList<>();
        List<Integer> codeNo = new ArrayList<>();
        codeTemp.addAll(codeList);
        codeNo.addAll(codeList);

        codeTemp.retainAll(codeYes);
        codeNo.removeAll(codeTemp);

        String strYes = StringUtils.join(codeYes, ",");
        String strNo = StringUtils.join(codeNo, ",");

        Integer yesCount = organizationCountService.selectVolunteerCount(strYes, 2);
        Integer noCount = organizationCountService.selectVolunteerCount(strNo, 2);

        List<GroupVolunteer> yesVolList = organizationCountService.selectGroupVolunteer(strYes, 2, startDate, endDate);
        List<GroupVolunteer> noVolList = organizationCountService.selectGroupVolunteer(strNo, 2, startDate, endDate);

        int yesGroup = 0;
        int groupTemp = 0;
        for (GroupVolunteer groupVolunteer : yesVolList) {
            if (groupVolunteer.getGroupId() != groupTemp) {
                yesGroup = yesGroup + 1;
                groupTemp = groupVolunteer.getGroupId();
            }
        }
        allGroup = allGroup + codeYes.size();
        allSign = allSign + yesCount;
        hasGroup = hasGroup + yesGroup;
        hasSign = hasSign + yesVolList.size();
        resultList.add(VolunteerCountResponseVo.build(yes, codeYes.size(), yesCount, yesGroup, yesVolList.size()));

        int noGroup = 0;
        groupTemp = 0;
        for (GroupVolunteer groupVolunteer : noVolList) {
            if (groupVolunteer.getGroupId() != groupTemp) {
                noGroup = noGroup + 1;
                groupTemp = groupVolunteer.getGroupId();
            }
        }
        allGroup = allGroup + codeNo.size();
        allSign = allSign + noCount;
        hasGroup = hasGroup + noGroup;
        hasSign = hasSign + noVolList.size();
        resultList.add(VolunteerCountResponseVo.build(no, codeNo.size(), noCount, noGroup, noVolList.size()));

        resultList.add(VolunteerCountResponseVo.build(count, allGroup, allSign, hasGroup, hasSign));

        return new ListDataResponseVo<>(StatusCode.SUCCESS.getStatusCode(), StatusCode.SUCCESS.getStatusMessage(), resultList);
    }
}
